/*****************************************************************************
 * file  : test.c
 * creat : apleilx
 * data  : 2017/03/02
 *******************************************************************************/
#define osObjectsCreat // define objects in rtxapp module
#include "os_obj.h"	   // RTOS object definitions
#include "mem_alloc.h"

void tx_filex_application_define(void);

/*******************************************************************************
 * @brief  任务定义
 *******************************************************************************/
osThreadDef(thd_console, task_console, 10, 0, 1024);
osThreadDef(thd_sys, task_system, 10, 0, 1024);

/*******************************************************************************
 * @brief  任务创建
 * \param[in] none
 * \retval: none
 *******************************************************************************/
int os_thread_init(void)
{
	os_thread_creat();
	
	return (0);
}

/*----------------------------------------------------------------------------
 *  creat thread object
 *---------------------------------------------------------------------------*/
int os_thread_creat(void)
{
	os_obj_creat();

	osThreadCreate(osThread(thd_console), "CONSOLE TASK");

	osThreadCreate(osThread(thd_sys), "SYSTEM TASK");

	// tx_filex_application_define();

	return 0;
}

/*----------------------------------------------------------------------------
 *  creat os object
 *---------------------------------------------------------------------------*/
int os_obj_creat(void)
{
	/* creat mutex */
	tx_mutex_create(&os_obj.mutex_printf,
					"mutex_printf",
					TX_NO_INHERIT); // no prio
	os_obj.mid_printf = &os_obj.mutex_printf;

	tx_mutex_create(&os_obj.mutex_common,
					"mutex_common",
					TX_NO_INHERIT); // no prio
	os_obj.mid_common = &os_obj.mutex_common;

	tx_mutex_create(&os_obj.mutex_mem,
					"mutex_mem",
					TX_NO_INHERIT); // no prio
	os_obj.mid_mem = &os_obj.mutex_mem;

	/* creat quene */
	tx_queue_create(&os_obj.quene_tst,			   // Pointer to queue control block
					"tst quene",				   // Pointer to queue name
					1,							   // Size of each queue message (Number of ULONG)
					os_obj.quene_tst_mem,		   // Starting address of the queue area
					sizeof(os_obj.quene_tst_mem)); // Number of bytes in the queue
	os_obj.qid_tst = &os_obj.quene_tst;

	/* creat event */

	tx_event_flags_create(&os_obj.event_mb,
						  "event mb");
	os_obj.eid_mb = &os_obj.event_mb;

	/* creat semaphore */
	tx_semaphore_create(&os_obj.sem_eth,
						"sem eth",
						1); // init val
	os_obj.sid_eth = &os_obj.sem_eth;

	tx_semaphore_create(&os_obj.sem_mb,
						"sem mb",
						1); // init val
	os_obj.sid_mb = &os_obj.sem_mb;

	return (0);
}

/*------------------------------------------------------------------------------
 *  task stack used
 *----------------------------------------------------------------------------*/
int32_t os_task_stk_used(osThreadId tid)
{
	uint32_t start, end, unused;

	start = (uint32_t)tid->tx_thread_stack_start;
	end = (uint32_t)tid->tx_thread_stack_end;

	unused = start;

	while (inpw(unused) == 0xEFEFEFEF && inpw(unused + 4) == 0xEFEFEFEF)
	{
		unused += 8;
	}

	return ((end + 1) - unused);
}

/*------------------------------------------------------------------------------
 *  task info
 *----------------------------------------------------------------------------*/
void tx_task_info(void)
{
	extern TX_THREAD *_tx_thread_created_ptr;
	TX_THREAD *tid = _tx_thread_created_ptr;

	dbg_print("===========================================================\n");
	dbg_print("==================CPU USAGE : %5.2f%% ======================\n",
			  0);
	dbg_print("===========================================================\n");

	do
	{
		int32_t stk_used = os_task_stk_used(tid);

		dbg_print("prio: %-3d, run count: %-8d :: stack (%08x - %08x), "
				  "size %5d, used %5d # %-3d%% :: %s\n",
				  tid->tx_thread_priority,
				  tid->tx_thread_run_count,
				  tid->tx_thread_stack_start,
				  tid->tx_thread_stack_end,
				  tid->tx_thread_stack_size,
				  stk_used,
				  stk_used * 100 / tid->tx_thread_stack_size,
				  tid->tx_thread_name);

		tid = tid->tx_thread_created_next;
	} while (tid && tid != _tx_thread_created_ptr);
}
